home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / xlib50.zip / EASYX.DOC < prev    next >
Text File  |  1995-02-11  |  28KB  |  847 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.                             EASYX PROGRAMMER'S MANUAL
  30.                                    VERSION 2.0
  31.  
  32.                               (DOS Extender Library)
  33.  
  34.                                 TechniLib Company
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.                   Copyright 1993-1995, by TechniLib (TM) Company
  61.                                All Rights Reserved
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.                           TERMS OF USE AND DISTRIBUTION
  69.  
  70.  
  71.        XLIB is a shareware product; therefore, unregistered copies of XLIB are
  72.   made available free of charge so that potential purchasers will have the
  73.   opportunity to examine and test the software before committing payment.
  74.   Distribution of unregistered copies of XLIB to other potential users is also
  75.   permitted and appreciated.  However, usage and distribution of XLIB must
  76.   conform to the following conditions.  In the following statement, the term
  77.   "commercial distribution," includes shareware distribution.
  78.  
  79.   1) XLIB and accompanying software must be distributed together in copies of
  80.   the original archive provided by TechniLib.  Neither the archive nor
  81.   individual files therein may be modified.
  82.  
  83.   2) The XLIB archive may be distributed in combination with other shareware
  84.   products; however, the XLIB archive may not be distributed with other
  85.   commercially distributed software without written consent of TechniLib.
  86.  
  87.   3) Copies of XLIB which have been used to develop software for commercial
  88.   distribution must be registered before such software is marketed.  Copies of
  89.   XLIB which have been used to develop noncommercial software must be registered
  90.   if such software is to be regularly used either by the developer or others.
  91.  
  92.   4) Commercially distributed software must embed XLIB procedures in the
  93.   software code.  Files contained in the XLIB archive may not be placed in the
  94.   distribution media.
  95.  
  96.   5) XLIB is designed to offer a set of services to other executable code.  XLIB
  97.   may not be used to develop software for commercial distribution which will
  98.   essentially offer any of these same services to other executable code.
  99.   Exceptions to this condition require written consent of TechniLib.
  100.  
  101.   6) Rights afforded by registering a single copy of XLIB pertain only to a
  102.   single computer.
  103.  
  104.   7) XLIB may be registered for a fee of $50.00 per copy.  Accompany payment
  105.   with return address.  Registrants will be entitled to the most recent version
  106.   of the XLIB archive.
  107.  
  108.  
  109.                               DISCLAIMER OF WARRANTY
  110.  
  111.  
  112.        XLIB AND ALL ACCOMPANYING SOFTWARE AND LITERATURE ARE DISTRIBUTED WITH
  113.   THE EXCLUSION OF ANY AND ALL IMPLIED WARRANTIES, AND WITH THE EXCLUSION OF
  114.   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  TechniLib
  115.   SHALL HAVE NO LIABILITY FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  116.   RESULTING FROM THE USE OF XLIB OR ACCOMPANYING MATERIALS.  The user assumes
  117.   the entire risk of using this software.
  118.  
  119.  
  120.                   Copyright 1993-1995, by TechniLib (TM) Company
  121.                                All Rights Reserved
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.                                 TABLE OF CONTENTS
  129.  
  130.  
  131.   CHAPTERS
  132.                                                                       Page
  133.   1. Introduction                                                        1
  134.   2. Initialization of EASYX                                             2
  135.   3. Memory Management                                                   3
  136.   4. Memory-Mapped Input/Output                                          6
  137.   5. File Management                                                     7
  138.  
  139.  
  140.   EXAMPLES
  141.                                                                       Page
  142.   1.  EASYX Memory Management                                            5
  143.   2.  EASYX File Management                                             10
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150.                                  1. Introduction
  151.  
  152.  
  153.        EASYX is a DOS extender library intended for programmers who are
  154.   unfamiliar with assembly language.  EASYX allows real-mode high-level
  155.   languages to perform transfers between extended memory and conventional memory
  156.   or between extended memory and disk files.  Many programmers need a DOS
  157.   extender merely to afford real-mode languages access to extended memory.  In
  158.   such cases, EASYX is a simple and powerful alternative.
  159.        EASYX is actually little more than a real-mode interface to XLIB.  The
  160.   source code for EASYX is supplied in the XLIB archive (EASYX.ASM).  Assembly
  161.   language programmers may be interested in examining this code to learn more
  162.   about working with XLIB.  This code has been assembled and then linked with
  163.   XLIB.LIB to create EASYX.LIB.
  164.        The EASYX library is provided in two formats - one for Microsoft
  165.   languages and the other for Borland languages.  Microsoft programmers should
  166.   use EASYX.LIB.  Borland programmers should use EASYXB.LIB.  The respective C
  167.   header files are EASYX.H and EASYXB.H.  Programmers using other languages will
  168.   have to write their own prototypes for EASYX procedures.  These prototypes
  169.   should declare all EASYX procedures as far procedures conforming to the PASCAL
  170.   calling and naming convention.  Prototypes for Microsoft BASIC 7.0 are
  171.   presented in the files EASYXEX1.BAS and EASYXEX2.BAS.
  172.        The programmer might prefer to use EASYXE.LIB rather than EASYX.LIB.  The
  173.   former has CPU exception trapping capabilities whereas the latter does not.
  174.   EASYXE.LIB will always trap exceptions occurring in protected mode.  It can
  175.   also trap real-mode exceptions provided that a DPMI 1.0 host is installed.
  176.   Borland programmers should use EASYXEB.LIB.  C and C++ programmers should
  177.   continue to use EASYX.H or EASYXB.H for header files.
  178.        Most EASYX procedures can return error codes.  These are always XLIB
  179.   error codes.  The codes are explained in the XLIB documentation.
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.                                         1
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.                             2. Initialization of EASYX
  215.  
  216.  
  217.        EASYX requires no initialization; however, the XLIB library which has
  218.   been linked with EASYX must be initialized before any EASYX procedures are
  219.   called.  XLIB is initialized by calling INITXLIB.  INITXLIB returns an error
  220.   code in DX:AX; therefore, it should be implemented as a long integer function.
  221.   The following code demonstrates initialization in Microsoft C:
  222.  
  223.  
  224.   extern unsigned long __far __pascal INITXLIB(void);
  225.  
  226.   void main(void)
  227.   {
  228.     unsigned long errcode;
  229.     errcode = INITXLIB();
  230.     if(errcode != 0)
  231.     {
  232.       printf("Initialization error:  %lX",errcode);
  233.       return;
  234.     }
  235.   .
  236.   .
  237.   .
  238.  
  239.        An explanation of possible error codes is presented in the XLIB
  240.   documentation.  The most common error is caused by insufficient conventional
  241.   memory.  INITXLIB will attempt to allocate a small amount of conventional
  242.   memory through DOS; however, many high-level languages automatically claim all
  243.   available DOS memory, even though only a small percentage of this memory may
  244.   actually be used.  The programmer must therefore release a portion of this
  245.   memory back to DOS before calling INITXLIB.  This process is illustrated for
  246.   the Borland Turbo Assembler in the file EXAMP1B.ASM, and for Microsoft BASIC
  247.   in EASYXEX1.BAS.  C and C++ programmers need not be concerned with this matter
  248.   because these languages allocate DOS memory dynamically.
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.                                         2
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.                                3. Memory Management
  279.  
  280.  
  281.        High-level languages confined to real mode are incapable of addressing
  282.   extended memory; consequently, such languages must communicate with extended
  283.   memory through buffers in conventional memory.  EASYX provides several
  284.   procedures to facilitate this process.
  285.        Extended memory should always be allocated with the procedure XMALLOC
  286.   before it is addressed.  Attempted transfers to or from unallocated memory may
  287.   lead to page faults (exception 14), or to corruption of resident software.
  288.   XMALLOC returns a long integer error code; therefore, it should be implemented
  289.   as a long integer function.  The following Microsoft C prototype shows the
  290.   structure of XMALLOC:
  291.  
  292.  
  293.   extern unsigned long __far __pascal XMALLOC(unsigned long nobytes, unsigned
  294.      long __far *address, unsigned long __far *size, unsigned long __far
  295.      *handle);
  296.  
  297.   where:
  298.   nobytes  = The requested size for the extended memory block.
  299.   *address = A far pointer to an unsigned long integer variable which will
  300.              receive the linear address of the allocated block.
  301.   *size    = A far pointer to an unsigned long integer variable which will
  302.              receive the actual size of the allocated extended memory block.
  303.              The actual size will always be at least as large as the requested
  304.              size.
  305.   *handle  = A far pointer to an unsigned long integer variable which will
  306.              receive a handle for the allocated extended memory block.  The
  307.              handle must be used to release the block.
  308.  
  309.  
  310.        An extended memory block can be released with the XFREE procedure.  XFREE
  311.   is also a long integer function which returns an error code.  The C prototype
  312.   of this procedure is:
  313.  
  314.  
  315.   extern unsigned long __far __pascal XFREE(unsigned long handle);
  316.  
  317.   where:  handle = The handle assigned to the block by XMALLOC.
  318.  
  319.  
  320.        All extended memory is automatically released upon program termination;
  321.   consequently, XFREE will not be necessary for most programs.
  322.        If DPMI 1.0 is installed, then version 2.0 of EASYX has the ability to
  323.   manage uncommitted memory.  Uncommitted memory is a logical address space with
  324.   no physical memory assigned to it.  Physical memory is committed (mapped) to
  325.   addresses within the space when they are accessed.  Uncommitted memory becomes
  326.   useful when a program needs to manage an array of uncertain size.  The array
  327.   can be dimensioned to be very large without exhausting physical memory by
  328.   situating the array over uncommitted memory.  Large amounts of memory will
  329.   therefore be used only when it is needed.
  330.        The procedure for allocating uncommitted memory is XUMALLOC.  It has
  331.   exactly the same prototype as XMALLOC.
  332.  
  333.  
  334.  
  335.                                         3
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.        After physical memory has been mapped into an uncommitted address space,
  343.   the programmer might wish to restore part or all of the address space back to
  344.   uncommitted state.  This releases the physical memory allocated to the space
  345.   so that it can be used for other purposes.  EASYX contains a routine called
  346.   XUNCOMMIT to perform such tasks.  The C prototype for this routine is:
  347.  
  348.  
  349.   extern unsigned long __far __pascal XUNCOMMIT(unsigned long handle, unsigned
  350.      long startoffset, unsigned long nobytes)
  351.  
  352.   where:
  353.   handle      = The handle of a memory block previously allocated with XUMALLOC.
  354.   startoffset = The offset within the block at which memory is to be released.
  355.   nobytes     = The number of bytes to release.
  356.  
  357.  
  358.        DPMI hosts will almost invariable map physical memory at 1000H boundaries
  359.   and in units of 1000H bytes.  Therefore, both startoffset and nobytes should
  360.   be even multiples of 1000H (4096).  If this is not the case, then XUNCOMMIT
  361.   will round these variables down to the next even multiple.
  362.        XUNCOMMIT releases physical memory backing an address space, but not the
  363.   address space itself.  Use XFREE to release both the address space and all
  364.   physical memory mapped within it.
  365.        Transfers between conventional memory and extended memory can be
  366.   accomplished with the MOVMEM procedure.  The prototype for MOVMEM is:
  367.  
  368.  
  369.   extern void __far __pascal MOVMEM(unsigned long destadr, unsigned long
  370.      sourceadr, unsigned long nobytes);
  371.  
  372.   where:
  373.   destadr   = The linear address of the destination memory.
  374.   sourceadr = The linear address of the source memory.
  375.   nobytes   = The number of bytes to be transferred.
  376.  
  377.  
  378.        MOVMEM may actually be used to transfer memory between any source and
  379.   destination.  The destination block and source block may also be overlapped.
  380.        MOVMEM transfers are faster than XMS or INT 15H because MOVMEM uses 32-
  381.   bit instructions.  MOVMEM also exposes to less risk of losing an interrupt.
  382.        MOVMEM is a reentrant procedure, so it may be safely called within
  383.   interrupt handlers.  When MOVMEM is being used in a hardware interrupt
  384.   handler, the handler should be installed after the call to INITXLIB to prevent
  385.   a call to MOVMEM before protected-mode structures have been initialized.
  386.        Real-mode programs use segment addresses instead of linear addresses.
  387.   EASYX includes a procedure called LINADR which computes linear addresses from
  388.   segment addresses.  The prototype for LINADR is:
  389.  
  390.  
  391.   extern unsigned long __far __pascal LINADR(void __far *ptr);
  392.  
  393.  
  394.        The following program uses the procedures presented in this section.  The
  395.   file EASYXEX1.BAS contains a Microsoft BASIC 7.0 version of the program.
  396.  
  397.  
  398.  
  399.                                         4
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.   Example 1:  EASYX Memory Management
  407.   _____________________________________________________________________________
  408.   #include <stdio.h>
  409.   #include <easyx.h>
  410.  
  411.   void main(void)
  412.   {
  413.     unsigned long errcode, nobytes, xaddress, xsize, xhandle, bufferaddress;
  414.     long buffer[1024];            /*4k buffer*/
  415.  
  416.     errcode = INITXLIB();         /*Initialize XLIB*/
  417.     if(errcode != 0)
  418.     {
  419.       printf("Library initialization error:  %lX\n",errcode);
  420.       return;
  421.     }
  422.  
  423.     nobytes = 0x10000;            /*Allocate 64k of extended memory*/
  424.     errcode = XMALLOC(nobytes, &xaddress, &xsize, &xhandle);
  425.     if(errcode != 0)
  426.     {
  427.       printf("Memory allocation error:  %lX\n",errcode);
  428.       return;
  429.     }
  430.  
  431.     bufferaddress = LINADR(buffer);          /*Get linear address of buffer*/
  432.     MOVMEM(xaddress, bufferaddress, 4096);   /*Transfer buffer to extended*/
  433.     MOVMEM(bufferaddress, xaddress, 4096);   /*Transfer extended to buffer*/
  434.  
  435.     errcode = XFREE(xhandle);     /*Release the extended memory*/
  436.     if(errcode != 0)
  437.       printf("Memory release error:  %lX\n",errcode);
  438.   }
  439.   _____________________________________________________________________________
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.                                         5
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.                           4. Memory-Mapped Input/Output
  471.  
  472.  
  473.        On 386 and higher machines, memory reads and writes may undergo address
  474.   translation so that the address which is physically accessed may be different
  475.   from the address specified in the read/write instruction.  The physically
  476.   accessed address is the "physical address."  The address specified by the
  477.   read/write instruction is the "logical address."  Normally programmers need
  478.   not be concerned with the difference; however, this is not the case if the
  479.   program must access an IO device which maps to a fixed physical address.  In
  480.   such cases, the programmer must obtain a logical address which corresponds to
  481.   the physical address of the IO device.  EASYX contains a procedure called
  482.   MAPIOMEM which will map a specified physical address into a logical address
  483.   space.  MAPIOMEM is a long integer function which returns an error code.  The
  484.   prototype for MAPIOMEM is:
  485.  
  486.  
  487.   extern unsigned long __far __pascal MAPIOMEM(unsigned long physaddress,
  488.      unsigned long size, unsigned long __far *logaddress);
  489.  
  490.   where:
  491.   physaddress = The beginning physical address for the IO device.
  492.   size        = The size of the physical address block in bytes.
  493.   *logaddress = A far pointer to an unsigned long integer which is to receive
  494.                 the assigned logical address.  Access the IO device at this
  495.                 address.
  496.  
  497.  
  498.        MAPIOMEM will sometimes return errors upon attempts to map physical
  499.   addresses in the first megabyte.
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.                                         6
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.                                 5. File Management
  535.  
  536.  
  537.        EASYX includes procedures which can transfer data between extended memory
  538.   and files.  These procedures can load files to extended memory or save
  539.   extended memory to files.  They can read and write files either sequentially
  540.   or randomly.
  541.        All EASYX file management routines will receive and return values in a
  542.   contiguous block of memory called a "file control block" (not to be confused
  543.   with DOS file control blocks).  The file control block must be located in
  544.   conventional memory and must have the following form:
  545.  
  546.  
  547.   Field Name   Field Type        Field Description
  548.   ----------   ----------        -----------------
  549.   CONDCODE     unsigned long     Condition code from file operation
  550.   FNAME        char[68]          File path and name (zero terminated string)
  551.   FHANDLE      unsigned int      File handle assigned by DOS
  552.   FPTRMODE     unsigned int      File pointer mode
  553.   FPTR         unsigned long     File pointer
  554.   BLKADR       unsigned long     Memory source/destination address
  555.   BLKSIZE      unsigned long     Size of source/destination block in bytes
  556.   BUFADR       unsigned long     Buffer address (conventional memory)
  557.   BUFSIZE      unsigned int      Buffer size in bytes
  558.   CONTROL      unsigned int      Control word
  559.  
  560.  
  561.        CONDCODE is used to return error codes.  CONDCODE should be situated at
  562.   the starting address of the control block.
  563.        FNAME is a zero-terminated ASCII string defining the file path and name.
  564.   There cannot be more than 68 characters in this string, including the
  565.   termination character.
  566.        BLKADR and BLKSIZE define the source/destination memory block for the
  567.   transfer.  This block may be in either conventional or extended memory.
  568.   BLKADR is a linear address.
  569.        XLIB uses DOS to access the disk.  DOS cannot read or write to extended
  570.   memory; consequently, a conventional memory buffer must be set up for the DOS
  571.   transfers.  File management routines shift to protected mode to perform
  572.   transfers between the buffer and the source/destination memory.  BUFADR and
  573.   BUFSIZE define the conventional memory buffer.  BUFADR is a linear address.
  574.        For fastest transfers, the memory block and the buffer should be DWORD
  575.   aligned and should have sizes equal to an integer multiple of four.
  576.        FPTR and FPTRMODE specify the file pointer setting to be used before
  577.   intrafile transfers to or from the disk.  FPTRMODE specifies how FPTR is to be
  578.   interpreted.  The following values are valid for FPTRMODE:
  579.  
  580.  
  581.   FPTRMODE    FPTR Interpretation
  582.   --------    -------------------
  583.   0           Unsigned offset from the beginning of the file
  584.   1           Signed offset from the current file pointer
  585.   2           Signed offset from the end of the file
  586.   3           FPTR is ignored.  Use current file pointer (sequential mode)
  587.  
  588.  
  589.  
  590.  
  591.                                         7
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.        CONTROL is not used in the present version of EASYX.  All bits in control
  599.   should be set to zero.
  600.        Since these routines perform disk operations, special precautions should
  601.   be taken to ensure that parameters in the file control block are properly
  602.   defined before performing calls.  In particular, one should always make sure
  603.   that the source/destination memory block and the conventional memory buffer
  604.   are properly defined.  A safe rule is to simply set the buffer size to zero
  605.   because this forces EASYX to supply a buffer when opening or creating the
  606.   file.
  607.        EASYX file routines should not be called within interrupt handlers
  608.   because all of these routines use DOS.
  609.        All EASYX file routines receive a single argument; namely, the far
  610.   address of the control block.  Prototypes for the file routines are:
  611.  
  612.  
  613.   extern void __far __pascal XFCREATE(void __far *controlblock);
  614.   extern void __far __pascal XFOPEN(void __far *controlblock);
  615.   extern void __far __pascal XFCLOSE(void __far *controlblock);
  616.   extern void __far __pascal XFLOAD(void __far *controlblock);
  617.   extern void __far __pascal XFSAVE(void __far *controlblock);
  618.   extern void __far __pascal XFREAD(void __far *controlblock);
  619.   extern void __far __pascal XFWRITE(void __far *controlblock);
  620.  
  621.  
  622.        The following is a detailed explanation of each of these procedures:
  623.  
  624.  
  625.   XFCREATE (Create File)
  626.   Purpose:  Create and open a new file of specified name in specified directory.
  627.   Control Block at Call:  FNAME = file path and name.
  628.   Control Block at Return:  CONDCODE = error code.  If CONDCODE = 0, then
  629.   FHANDLE = file handle assigned by DOS.  If the procedure is called with
  630.   BUFSIZE = 0, then EASYX will set BUFADR and BUFSIZE to its own internal
  631.   buffer.
  632.   Details:
  633.      If the file already exists, then it will be truncated to zero length.
  634.      Files created by this routine will be given both read and write access.
  635.  
  636.   XFOPEN (Open File)
  637.   Purpose:  Open existing file of specified name in specified directory.
  638.   Control Block at Call:  FNAME = file path and name.
  639.   Control Block at Return:  CONDCODE = error code.  If CONDCODE = 0, then
  640.   FHANDLE = file handle assigned by DOS.  If the procedure is called with
  641.   BUFSIZE = 0, then EASYX will set BUFADR and BUFSIZE to its own internal
  642.   buffer.
  643.   Details:  The file is opened for both read and write access.
  644.  
  645.   XFCLOSE (Close File)
  646.   Purpose:  Close previously opened file.
  647.   Control Block at Call:  FHANDLE = file handle.
  648.   Control Block at Return:  CONDCODE = error code.
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.                                         8
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.   XFSAVE (Save File)
  663.   Purpose:  Create file with contents equal to specified memory block.
  664.   Control Block at Call:  FNAME = file path and name.  BLKADR/BLKSIZE = address
  665.   and size of memory block to provide file contents.  BUFADR/BUFSIZE = address
  666.   and size of conventional memory buffer.
  667.   Control Block at Return:  CONDCODE = error code.
  668.   Details:
  669.      The file cannot already be open.  The file is both created and closed by
  670.   this routine.
  671.      This routine will replace any previously existing file named FNAME.
  672.      BLKADR/BLKSIZE may define a conventional memory block provided that this
  673.   block is not overlapped by BUFADR/BUFSIZE.
  674.      If this routine is called with BUFSIZE = 0, then EASYX will automatically
  675.   supply a buffer.
  676.  
  677.   XFLOAD (Load File)
  678.   Purpose:  Load file contents to specified memory block.
  679.   Control Block at Call:  FNAME = file path and name.  BLKADR/BLKSIZE = address
  680.   and size of memory block to receive file contents.  BUFADR/BUFSIZE = address
  681.   and size of conventional memory buffer.
  682.   Control Block at Return:  CONDCODE = error code.  If CONDCODE = 0, then
  683.   BLKSIZE = actual number of bytes transferred.
  684.   Details:
  685.      The file cannot already be open.  The file is both opened and closed by
  686.   this routine.
  687.      The value of BLKSIZE as of call is interpreted as an upper limit on the
  688.   number of bytes to transfer.  The entire file is loaded provided that it does
  689.   not contain more than BLKSIZE bytes.
  690.      BLKADR/BLKSIZE may define a conventional memory block provided that this
  691.   block is not overlapped by BUFADR/BUFSIZE.
  692.      If this routine is called with BUFSIZE = 0, then EASYX will automatically
  693.   supply a buffer.
  694.  
  695.   XFWRITE (Write to File)
  696.   Purpose:  Write specified memory block to specified location in open file.
  697.   Control Block at Call:  FHANDLE = file handle.  FPTR/FPTRMODE = file pointer
  698.   setting for beginning of transfer.  BLKADR/BLKSIZE = address and size of
  699.   memory block to provide file contents.  BUFADR/BUFSIZE = address and size of
  700.   conventional memory buffer.
  701.   Control Block at Return:  CONDCODE = error code.
  702.   Details:
  703.      The file must be opened with XFOPEN or XFCREATE before using this routine.
  704.      BLKADR/BLKSIZE may define a conventional memory block provided that this
  705.   block is not overlapped by BUFADR/BUFSIZE.
  706.      Sequential transfers should set FPTRMODE = 3 for fastest execution.
  707.  
  708.   XFREAD (Read From File)
  709.   Purpose:  Load specified memory block from specified location in open file.
  710.   Control Block at Call:  FHANDLE = file handle.  FPTR/FPTRMODE = file pointer
  711.   setting for beginning of transfer.  BLKADR/BLKSIZE = address and size of
  712.   memory block to receive file contents.  BUFADR/BUFSIZE = address and size of
  713.   conventional memory buffer.
  714.   Control Block at Return:  CONDCODE = error code.  If CONDCODE = 0, then
  715.   BLKSIZE = the actual number of bytes transferred.
  716.  
  717.  
  718.  
  719.                                         9
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.   Details:
  727.      The file must be opened with XFOPEN or XFCREATE before using this routine.
  728.      BLKADR/BLKSIZE may define a conventional memory block provided that this
  729.   block is not overlapped by BUFADR/BUFSIZE.
  730.      Sequential transfers should set FPTRMODE = 3 for fastest execution.
  731.  
  732.        The following C program illustrates the usage of some of the above
  733.   procedures.  A BASIC translation of this program is in EASYXEX2.BAS.
  734.  
  735.  
  736.   Example 2:  EASYX File Management
  737.   _____________________________________________________________________________
  738.   #include <stdio.h>
  739.   #include <string.h>
  740.   #include <easyx.h>
  741.  
  742.   void main (void)
  743.   {
  744.     unsigned int i;
  745.     unsigned long errcode, nobytes, xaddress, xsize, handle, arrayaddress;
  746.     int array[100];
  747.     struct xfile fb;                 /*Declare file control block*/
  748.  
  749.     errcode = INITXLIB();            /*Initialize XLIB*/
  750.     if(errcode != 0)
  751.     {
  752.       printf("Library initialization error:  %lX\n",errcode);
  753.       return;
  754.     }
  755.  
  756.     nobytes = 0x10000;               /*Allocate 64k of extended memory*/
  757.     errcode = XMALLOC(nobytes,&xaddress,&xsize,&handle);
  758.     if(errcode != 0)
  759.     {
  760.       printf("Extended memory allocation error:  %lX\n",errcode);
  761.       return;
  762.     }
  763.  
  764.     for(i = 0; i < 100; i++)         /*Put something in array[]*/
  765.       array[i] = i;
  766.  
  767.     arrayaddress = LINADR(array);    /*Compute linear address of array[]*/
  768.  
  769.     fb.condcode = 0;                 /*Set control block to create file*/
  770.     strcpy(fb.fname,"junk.dat");     /*Specify file name*/
  771.     fb.blkadr = arrayaddress;        /*Will transfer array[] to the file*/
  772.     fb.blksize = 200;                /*There are 200 bytes in array[]*/
  773.     fb.bufsize = 0;                  /*Force XLIB to use its internal buffer*/
  774.     XFSAVE(&fb);                     /*Create file and save array[] to it*/
  775.     if(fb.condcode != 0)
  776.     {
  777.       printf("File save error:  %lX\n",fb.condcode);
  778.       return;
  779.     }
  780.  
  781.  
  782.  
  783.                                         10
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.     XFOPEN(&fb);                     /*Reopen the file*/
  792.     if(fb.condcode != 0)
  793.     {
  794.       printf("File open error:  %lX\n",fb.condcode);
  795.       return;
  796.     }
  797.  
  798.     fb.blkadr = xaddress;         /*Prepare to transfer the file to extended*/
  799.     fb.blksize = 100;             /*Will transfer only 100 bytes*/
  800.     fb.fptrmode = 0;              /*File pointer is relative to start of file*/
  801.     fb.fptr = 100;                /*Set file pointer to 50th element*/
  802.     XFREAD(&fb);                  /*Read last 50 elements to extended*/
  803.     if(fb.condcode != 0)
  804.     {
  805.       printf("File read error:  %lX\n",fb.condcode);
  806.       return;
  807.     }
  808.  
  809.     MOVMEM(arrayaddress,xaddress,100); /*Transfer file contents back to array[]
  810.  
  811.     XFCLOSE(&fb);                      /*Close the file*/
  812.     if(fb.condcode != 0)
  813.     {
  814.       printf("File close error:  %lX\n",fb.condcode);
  815.       return;
  816.     }
  817.  
  818.     errcode = XFREE(handle);           /*Release extended memory*/
  819.     if(errcode != 0)
  820.     {
  821.       printf("Memory release error:  %lX\n",errcode);
  822.       return;
  823.     }
  824.   }
  825.   _____________________________________________________________________________
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.                                         11